package com.tedu.startbooksstore.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.tedu.startbooksstore.ex.ServiceException;
import com.tedu.startbooksstore.pojo.dto.UserLoginDTO;
import com.tedu.startbooksstore.pojo.dto.UserRegDTO;
import com.tedu.startbooksstore.pojo.dto.UserUpdateDTO;
import com.tedu.startbooksstore.pojo.vo.UserListItemVO;
import com.tedu.startbooksstore.service.UserService;
import com.tedu.startbooksstore.web.JsonResult;
import com.tedu.startbooksstore.web.ServiceCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * 用户请求控制层
 */
@Api(tags = "01.用户管理模块")
@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;


    /**
     * 更改用户信息
     * @return : 更改用户信息成功
     */
    @ApiOperationSupport(order = 400)
    @ApiOperation("更改用户信息")
    @PostMapping("/updateById")
    public JsonResult<?> udpateById(UserUpdateDTO userUpdateDTO) {
        log.debug("开始处理业务:更改用户信息");

        userService.updateById(userUpdateDTO);

        return JsonResult.ok();
    }

    /**
     * 查询用户信息列表
     * @return : 查询到的用户信息列表
     */
    @ApiOperationSupport(order = 150)
    @ApiOperation("查询用户信息列表")
    @PostMapping("")
    public JsonResult<List<UserListItemVO>> select() {
        log.debug("开始处理业务:查询用户信息列表");

        List<UserListItemVO> list = userService.list();

        log.debug("查询到的用户信息列表为:{}",list);

        return JsonResult.ok(list);
    }

    /**
     * 根据ID查询用户信息
     * @param id : 需要查询信息的用户ID
     * @return : 查询到的用户信息
     */
    @ApiOperationSupport(order = 151)
    @ApiOperation("根据ID查询用户信息")
    @ApiImplicitParam(name = "id",value = "用户ID",required = true,dataType = "long")
    @PostMapping("/{id:[0-9]+}/select")
    public JsonResult<UserListItemVO> selectById(@Range(min = 1,message = "查询失败,ID无效")
                                         @PathVariable Long id) {
        log.debug("开始处理业务:查询ID为:{}的用户信息",id);

         UserListItemVO user = userService.selectById(id);

         log.debug("查询到的用户信息为:{}",user);

        return JsonResult.ok(user);
    }

    /**
     * 用户注册
     * @param userRegDTO  : 需要注册的用户
     * @return  : 返回给前端的数据
     */
    @ApiOperationSupport(order = 100)
    @ApiOperation("用户注册")
    @PostMapping("/reg")
    public JsonResult<?> reg(UserRegDTO userRegDTO){

        log.debug("开始处理请求:注册用户{}",userRegDTO);

        userService.register(userRegDTO);

        log.debug("用户:{}注册成功",userRegDTO.getUsername());
        return JsonResult.ok();
    }

    /**
     * 用户登录
     * @param userLoginDTO  : 需要登录的用户
     * @param session  : 登录成功的用户信息存放在 session 里面
     * @return  : 返回给前端的数据
     */
    @ApiOperationSupport(order = 101)
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public JsonResult<?> login(UserLoginDTO userLoginDTO,HttpSession session){
        log.debug("接收到用户:{}登录信息,开始处理登录业务...",userLoginDTO.getUsername());

        userService.login(userLoginDTO);

        session.setAttribute("user",userLoginDTO);

        log.debug("用户:{}登录成功",userLoginDTO.getUsername());

        return JsonResult.ok();

    }

    /**
     *  用户退出
     * @param session  : 从session中获取存放登录的用户信息,释放用户信息,退出登录
     * @return  : 将 session 存放的已登录用户信息 返回给前端
     */
    @ApiOperationSupport(order = 102)
    @ApiOperation("用户退出")
    @GetMapping("/getLoginUser")
    public JsonResult<UserLoginDTO> getLoginUser(HttpSession session){
        UserLoginDTO user = (UserLoginDTO) session.getAttribute("user");
        if (user==null){
            String message = "未登录";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("用户:{}已退出登录",user.getUsername());
        session.removeAttribute("user");
        return JsonResult.ok(user);
    }

}
